package com.blog.controller;
import com.blog.dto.FavoriteDTO;
import com.blog.pojo.*;
import com.blog.service.ArticleService;
import com.blog.service.CommentService;
import com.blog.service.FolloweeService;
import com.blog.service.UserService;
import com.blog.service.impl.ArticleServiceImpl;
import com.blog.service.impl.CommentServiceImpl;
import com.blog.service.impl.FolloweeServiceImpl;
import com.blog.service.impl.UserServiceImpl;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;
import java.util.stream.Collectors;

import static java.lang.System.out;
import static java.time.LocalDateTime.*;

@WebServlet("/articleServlet")
public class ArticleServlet extends BaseServlet {
    private ArticleService articleService = new ArticleServiceImpl();
    private CommentService commentService = new CommentServiceImpl();
    private UserService userService = new UserServiceImpl();
    private FolloweeService followeeService = new FolloweeServiceImpl();

    //查询--全部
    public String findAll(HttpServletRequest req, HttpServletResponse resp) {
        //获取参数--无参数
        //调用业务层
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("user");

        List<Articles> all = articleService.findAll();

        List<Integer> articleIds = all.stream().map(Articles::getId).collect(Collectors.toList());
        List<Start> starts = articleService.userLikedArticles(user.getId(), articleIds);
        List<Integer> startedArticleIds = starts.stream().map(Start::getArticleId).collect(Collectors.toList());

        for (Articles article : all) {
            Integer userId = article.getUserId();

            if (user != null) {
//                boolean like = articleService.userLiked(article.getId(), user.getId());
                boolean like = startedArticleIds.contains(article.getId());
                boolean favorite = articleService.userFavorited(article.getId(), user.getId());
                article.setUserLiked(like);
                article.setUserFavorited(favorite);

                boolean isAuthor = article.getUserId() == user.getId();
                article.setCanEdit(isAuthor);
                article.setCanDelete(isAuthor);
            }
            User user1 = userService.findById(userId);
            article.setUserName(user1.getUsername());

        }
        req.setAttribute("articleList", all);
        return "forward:/articleList.jsp";

    }

    //查询文章--标题
    public String findByTitle(HttpServletRequest req, HttpServletResponse resp) {
        //1.获取参数--标题+文章id
       // String title = req.getParameter("title");
        String id = req.getParameter("id");
        //登录验证
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null) {
            req.setAttribute("msg", "请先登录");
            return "forward:/login.jsp";
        } else {
            //验证文章是否存在
            int idInt = Integer.parseInt(id);
            Articles article = articleService.findById(idInt);
            if (article == null) {
                req.setAttribute("msg", "文章不存在");
                return "forward:/error.jsp";
            }
            int articleIdInt = article.getId();
            List<Comment> commentList = commentService.findByArticleId(articleIdInt);
            for (Comment comment : commentList) {
                Integer userId = comment.getUserId();
                User user1 = userService.findById(userId);
                comment.setUserName(user1.getUsername());
                //  设置按钮权限
                boolean isCommentOwner = comment.getUserId() == user.getId();
                boolean isArticleAuthor = article.getUserId() == user.getId();


                comment.setCanDelete(isCommentOwner || isArticleAuthor);
                comment.setCanEdit(isCommentOwner);
            }

            boolean liked = articleService.userLiked(article.getId(), user.getId());
            boolean favorited = articleService.userFavorited(article.getId(), user.getId());
            article.setUserLiked(liked);
            article.setUserFavorited(favorited);

            Integer userId = article.getUserId();
            User user1 = userService.findById(userId);
            article.setUserName(user1.getUsername());
            req.setAttribute("commentList", commentList);
            req.setAttribute("article", article);
            return "forward:/articleDetail.jsp";


        }

    }
    //查询文章--作者
    public String findByAuthor(HttpServletRequest req, HttpServletResponse resp) {
        //1.获取参数--标题
        String author = req.getParameter("author");
        //登录验证
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null) {
            req.setAttribute("msg", "请先登录");
            return "forward:/login.jsp";
        } else {
            //2.调用业务层
            List<Articles> byAuthor = articleService.findByAuthor(author);
            req.setAttribute("byAuthor", byAuthor);
            return "forward:/articleServlet?method=findByAuthor";
        }

    }

    public String update(HttpServletRequest req, HttpServletResponse resp) {
        //1.获取参数
        String id = req.getParameter("id");
        String title = req.getParameter("title");
        String content = req.getParameter("content");
        //登录验证
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null) {
            req.setAttribute("msg", "请先登录");
            return "forward:/login.jsp";
        }
        int userId = user.getId();
        int idInt = Integer.parseInt(id);
        boolean isArticleAuthor = articleService.findById(idInt).getUserId() == userId;

        if (!isArticleAuthor) {
            req.setAttribute("msg", "没有权限");
            return "forward:/error.jsp";
        }
        //2.调用业务层
        Articles articles = new Articles();
        articles.setId(idInt);
        articles.setTitle(req.getParameter("title"));
        articles.setContent(req.getParameter("content"));
        articles.setUpdatedAt(now());
        boolean update = articleService.update(articles);
        if (update) {
            return "forward:/articleServlet?method=findAll";
        } else {
            req.setAttribute("msg", "更新失败");
            return "forward:/error.jsp";


        }
    }


    //添加
    public String addArticle(HttpServletRequest req, HttpServletResponse resp) {
        //1.获取参数
        String title = req.getParameter("title");
        String content = req.getParameter("content");
        String userId = req.getParameter("userId");
        Byte status = Byte.parseByte(req.getParameter("status"));

        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("user");


        Articles articles = new Articles();
        articles.setTitle(title);
        articles.setContent(content);
        articles.setStatus(status);
        articles.setUserId(user.getId());
        articles.setCreatedAt(now());
        articles.setUpdatedAt(now());

        //调用业务层
        articleService.addArticle(articles);
        req.setAttribute("title", title);
        req.setAttribute("content", content);
        req.setAttribute("userId", userId);
        req.setAttribute("status", status);
        req.setAttribute("createdAt", now());
        req.setAttribute("updatedAt", now());

        return "forward:/articleServlet?method=findAll";
    }

    //删除
    public String delete(HttpServletRequest req, HttpServletResponse resp) {
        String id = req.getParameter("id");
        //登录验证
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null) {
            req.setAttribute("msg", "请先登录");
            return "forward:/login.jsp";
        }

        //获取用户id
        int userId = user.getId();
        int idInt = Integer.parseInt(id);
        Articles article = articleService.findById(idInt);
        if (article == null) {
            req.setAttribute("msg", "文章不存在");
            return "forward:/error.jsp";
        }
        boolean isArticleAuthor = article.getUserId() == userId;
        if (!isArticleAuthor) {
            req.setAttribute("msg", "无删除权限");
            return "forward:/error.jsp";
        }
        boolean delete = articleService.delete(idInt);
        if (delete) {//删除成功
            return "forward:/articleServlet?method=findAll";
        } else {
            req.setAttribute("msg", "删除失败");
            return "forward:/error.jsp";
        }
    }


    public String findById(HttpServletRequest req, HttpServletResponse resp) {
        String id = req.getParameter("id");
        //登录验证
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null) {
            req.setAttribute("msg", "请先登录");
            return "forward:/login.jsp";
        } else {
            int idInt = Integer.parseInt(id);
            Articles article = articleService.findById(idInt);
            User user1 = userService.findById(article.getUserId());
            article.setUserName(user1.getUsername());
            //article.setUserName(user.getUsername());
            req.setAttribute("article", article);
            return "forward:/articleDetail.jsp";
        }
    }

//    public String like(HttpServletRequest req, HttpServletResponse resp) {
//        String id = req.getParameter("id");
//        if (id != null) {
//        }
//        try {
//            Map<String, Object> map = new HashMap<>();
//            map.put("count", 10);
//            String jsonStr = JSONUtil.toJsonStr(map);
//            resp.getWriter().write(jsonStr);
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        }
//        return null;
//    }

    public String start(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String idStr = req.getParameter("id");
        PrintWriter out = resp.getWriter();
        //登录验证
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("user");

        if (user == null) {
            out.print("{\"error\":\"请先登录\"}");
            out.flush();
            return null;
        } else {
            int loginUserId = user.getId();
            int articleId = Integer.parseInt(idStr);
            // 2. 判断文章是否存在
            Articles article = articleService.findById(articleId);
            Integer userId = article.getUserId();
            if (article == null) {
                //  req.setAttribute("msg", "文章不存在");
                out.print("{\"error\":\"文章不存在\"}");
                out.flush();
                return null;
            } else {
                // 3. 判断当前用户是否已给这篇文章点过赞
                boolean exists = articleService.findStart(articleId, loginUserId, (byte) 1);
                if (exists) {
                    //再次点击点赞就取消点赞
                    articleService.deleteStart(articleId, loginUserId);
                    //经验值减3
                    boolean b = userService.reduceExperience(userId, 3);
                    if (!b) {
                        req.setAttribute("msg", "经验值减少失败");
                        return "forward:/error.jsp";
                    }
                    int experiencePoints = userService.findExperience(userId);
                    req.setAttribute("experiencePoints", experiencePoints);

                    req.setAttribute("title1", "取消点赞");
                } else {
                    Start start = new Start();
                    start.setArticleId(articleId);
                    start.setUserId(loginUserId);
                    start.setStart((byte) 1);
                    articleService.addStart(start);
                    //经验值加3
                    boolean b = userService.addExperience(loginUserId, 3);
                    if (!b) {
                        req.setAttribute("msg", "经验值增加失败");
                        return "forward:/error.jsp";
                    }
                    int experiencePoints = userService.findExperience(loginUserId);
                    req.setAttribute("experiencePoints", experiencePoints);
                    req.setAttribute("title2", "点赞成功");

                    //  return "forward:/articleServlet?method=detail&id=" + articleId;
                    // 返回 JSON
                }
                long startCount = articleService.findStartCount(articleId);
                req.setAttribute("startCount", startCount);
                articleService.updateStartCount(articleId, startCount);
                out.print("{\"count\":" + startCount + ",\"liked\":" + !exists + "}");
//                out.print("{\"count\":" + startCount + ",\"liked\":" + !exists + "}");
                out.flush();
            }
            return null;

        }

    }
    public String favorite(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String idStr = req.getParameter("id");
        PrintWriter out = resp.getWriter();
        //登录验证
        HttpSession session = req.getSession();
        User user = (User) session.getAttribute("user");
        if (user == null) {
            out.print("{\"error\":\"请先登录\"}");
            out.flush();
            return null;
        } else {
            int loginUserId = user.getId();
            int articleId = Integer.parseInt(idStr);
            // 2. 判断文章是否存在
            Articles article = articleService.findById(articleId);
            Integer userId = article.getUserId();
            if (article == null) {
                //  req.setAttribute("msg", "文章不存在");
                out.print("{\"error\":\"文章不存在\"}");
                out.flush();
                return null;
            } else {
                // 3. 判断当前用户是否已给这篇文章点收藏
                boolean exists = articleService.findFavorite(articleId, loginUserId, (byte) 1);
                if (exists) {
                    //再次点击收藏就取消收藏
                    articleService.deleteFavorite(articleId, loginUserId);
                    //经验值减1
                    boolean b = userService.reduceExperience(userId, 1);
                    if (!b) {
                        req.setAttribute("msg", "经验值减少失败");
                        return "forward:/error.jsp";
                    }
                    int experiencePoints = userService.findExperience(userId);
                    req.setAttribute("experiencePoints", experiencePoints);

                    req.setAttribute("title1", "取消收藏");
                } else {
                    Favorite favorite = new Favorite();
                    favorite.setArticleId(articleId);
                    favorite.setUserId(loginUserId);
                    favorite.setFavorite((byte) 1);
                    articleService.addFavorite(favorite);
                    //经验值加1
                    userService.addExperience(loginUserId, 1);
                    int experiencePoints = userService.findExperience(loginUserId);
                    req.setAttribute("experiencePoints", experiencePoints);
                    req.setAttribute("title2", "收藏成功");
                }
                long favoriteCount = articleService.findFavoriteCount(articleId);
                req.setAttribute("favoriteCount", favoriteCount);
                articleService.updateFavoriteCount(articleId, favoriteCount);
                //  return "forward:/articleServlet?method=detail&id=" + articleId;
                // 返回 JSON
                out.print("{\"count\":" + favoriteCount + ",\"liked\":" + !exists + "}");
                out.flush();


            }
            return null;

        }
    }

    public String userProfile(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //1.获取作者id
        String userId = req.getParameter("userId");
        //2.登录验证
        HttpSession session = req.getSession();
        User loginUser = (User) session.getAttribute("user");
        if (loginUser == null) {
            req.setAttribute("msg", "请先登录");
            return "forward:/login.jsp";
        }
        //获取作者名字
        int userIdInt = Integer.parseInt(userId);
        User user1 = userService.findById(userIdInt);
        String username = user1.getUsername();
        //判断登录人是不是文章作者
        boolean isOwner = loginUser.getId() == userIdInt;
        boolean isFollowed = followeeService.findByUserIdAndFolloweeId(loginUser.getId(), userIdInt) != null;
        req.setAttribute("isFollowed", isFollowed);
        //获取该作者所有文章
        List<Articles> articles = articleService.finbByUserId(userIdInt);
        for (Articles article : articles) {

             if (loginUser != null) {
                boolean like = articleService.userLiked(article.getId(), loginUser.getId());
                boolean favorite = articleService.userFavorited(article.getId(), loginUser.getId());
                article.setUserLiked(like);
                article.setUserFavorited(favorite);

                boolean isAuthor = article.getUserId() == loginUser.getId();
                article.setCanEdit(isAuthor);
                article.setCanDelete(isAuthor);

            }
        }
        // 获取关注数量
        int followeeCount = followeeService.findFolloweeCount(userIdInt);
      //获取粉丝数（service）
        int fanCount = followeeService.findFanCount(userIdInt);
        // 添加经验值获取逻辑
        int experiencePoints = userService.findExperience(userIdInt);

        req.setAttribute("followeeCount", followeeCount);
        req.setAttribute("fanCount", fanCount);
        req.setAttribute("experiencePoints", experiencePoints);
        req.setAttribute("user", user1);
        req.setAttribute("articles", articles);
        req.setAttribute("isOwner", isOwner);
        return "forward:/userProfile.jsp";
    }


   public String findByUserIdStatus(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        //登录验证
       HttpSession session=req.getSession();
       User user=(User)session.getAttribute("user");
       if(user==null){
           req.setAttribute("msg","请先登录");
           return "forward:/login.jsp";

       }
       //获取用户id
       int userId=user.getId();
       List<Articles> articles=articleService.findByUserIdAndStatus(userId, (byte) 0);
       req.setAttribute("articles",articles);
       return "forward:/userDrafts.jsp";

   }

public String findFavoriteList(HttpServletRequest req, HttpServletResponse resp){
        //获取数据
      String userId=req.getParameter("userId");
      //登录验证
        HttpSession session=req.getSession();
        User user=(User)session.getAttribute("user");
        if(user==null){
            req.setAttribute("msg","请先登录");
            return "forward:/login.jsp";
        }
        int userIdInt=Integer.parseInt(userId);

        List<Favorite> favoriteList=articleService.findFavoriteList(userIdInt);
         List<FavoriteDTO> dtoList = new ArrayList<>();
        for (Favorite favorite : favoriteList){

            Articles article=articleService.findById(favorite.getArticleId());
            User u=userService.findById(article.getUserId());
            FavoriteDTO dto = new FavoriteDTO();
            dto.setArticleId(article.getId());
            dto.setTitle(article.getTitle());
            dto.setContent(article.getContent());
            dto.setUsername(u.getUsername());
            dto.setCreateTime(favorite.getCreateTime());
            dtoList.add(dto);
        }

        req.setAttribute("favoriteList",dtoList);
        return "forward:/favoriteList.jsp";
}



}






















//    public static void main(String[] args) {
//        Test test = new Test();
//        test.count = 10;
//        test.liked = 1;
//
//        ReflectUtil.invoke(test, "show", "==============================", "----------------------------------");
//    }
//}
//
//class Test {
//    public int count;
//    public int liked;
//
//    public void show(String str, String str2) {
//        System.out.println(str);
//        System.out.println(str2);
//        System.out.println("count = " + count + ", liked = " + liked);
//    }
//
//}